﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Timers;
using System.Web;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using Helper.Bussiness;
using com.SEO.Business;
using System.Data;
using com.SEO.Model;

namespace Helper
{
    public class KeywordRankManage
    {
        private Timer _timer;
        private const string GoogleURL = "http://www.google.com/search?num=5&q={0}&btnG=Search&filter=0&oe=utf8";
        private const string YahooURL = "http://search.yahoo.com/search?p={0}&n=10";
        private const string GoogleRegex = "<h3 class=\"r\"><a href=\"(.*?&amp)";
        private const string YahooRegex = "<a id=\"link-[0-5]\"(.*?</a>)";
        private static int index = 0;
        private static int day = 0;

        public KeywordRankManage()
        {

        }

        public void RunTask()
        {
            if (_timer == null)
            {
                _timer = new Timer();
                _timer.Elapsed += new ElapsedEventHandler(GetRank);
                _timer.Interval = 60000;
                _timer.Enabled = true;
            }

            _timer.Start();
        }

        public void StopTask()
        {
            if (_timer != null)
            {
                _timer.Stop();
            }
        }

        private void GetRank(object sender, ElapsedEventArgs e)
        {
            RankManage rankManage = new RankManage();
            SiteManage siteManage = new SiteManage();
            KeywordManage keywordManage = new KeywordManage();
            DateTime dateNow = DateTime.Now.AddDays(day);
            CommSelect _commSelect = new CommSelect();
            ComHelp _comHelp = new ComHelp();

            while (true)
            {
                _comHelp.TableName = "StatisticsKeyword";
                _comHelp.SelectList = "*";
                _comHelp.SearchCondition = " 1 = 1";
                _comHelp.PageSize = 10;
                _comHelp.PageIndex = index;
                _comHelp.OrderExpression = " SiteID asc";

                DataTable dtbKeywords = _commSelect.ComSelect(ref _comHelp);
                List<RankInfo> lstRank = null;
                int nGoogle = 0;
                int nYahoo = 0;
                foreach (DataRow row in dtbKeywords.Rows)
                {
                    nGoogle = 0;
                    nYahoo = 0;
                    Guid keywordID = new Guid(row["KeywordID"].ToString());

                    // Check the current day has query rank or not.
                    lstRank = rankManage.getRankInfoByCondition(" KeywordID = '" + row["KeywordID"]
                        + "' and year(RankDate) = " + dateNow.Year
                        + " and month(RankDate) = " + dateNow.Month
                        + " and day(RankDate) = " + dateNow.Day);
                    if (lstRank.Count > 0)
                        continue;

                    SiteInfo siteInfo = siteManage.GetSiteInfoByID(row["SiteID"].ToString());
                    if (siteInfo != null)
                    {
                        try
                        {
                            nYahoo = GetYahooRank(siteInfo.SiteURL, row["Keyword"].ToString()) ? 1 : 0;
                            nGoogle = GetGoogleRank(siteInfo.SiteURL, row["Keyword"].ToString()) ? 1 : 0;

                            RankInfo rankInfo = new RankInfo();
                            rankInfo.RankId = Guid.NewGuid();
                            rankInfo.KeywordId = keywordID;
                            rankInfo.Google = nGoogle;
                            rankInfo.Yahoo = nYahoo;
                            rankInfo.RankDate = dateNow;

                            rankManage.AddRankInfo(rankInfo);
                        }
                        catch (Exception)
                        {
                        }
                    }
                    else
                    {
                        continue;
                    }
                }

                if (_comHelp.TotalPages == (index + 1))
                {
                    break;
                }

                ++index;
            }

            ++day;
        }

        private bool GetYahooRank(string strURL, string strkeyword)
        {
            return GetPosition(YahooURL, YahooRegex, strkeyword, strURL);
        }

        private bool GetGoogleRank(string strURL, string strkeyword)
        {
            return GetPosition(GoogleURL, GoogleRegex, strkeyword, strURL);
        }

        private static bool GetPosition(string strSearchEngineURL, string strRegex, string strkeyword, string strURL)
        {
            string search = string.Format(strSearchEngineURL, HttpUtility.UrlEncode(strkeyword));

            WebClient client = new WebClient();
            client.Encoding = Encoding.UTF8;
            string html = client.DownloadString(search);

            bool result = FindPosition(html, strRegex, strURL);
            client.Dispose();
            return result;

            //HttpWebRequest request = (HttpWebRequest)WebRequest.Create(search);
            //request.CookieContainer = new CookieContainer();
            //using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            //{
            //    using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
            //    {
            //        string html = reader.ReadToEnd();
            //        return FindPosition(html, strRegex, strURL);
            //    }
            //}
        }

        private static bool FindPosition(string html, string strRegex, string strURL)
        {
            MatchCollection matches = Regex.Matches(html, strRegex);

            for (int i = 0; i < matches.Count; i++)
            {
                string match = matches[i].Value;

                Debug.WriteLine(match);

                if (match.Contains(strURL) || match.Contains(strURL.Replace("www.","")))
                    return true;
            }

            return false;
        }
    }
}
